﻿#pragma once

#include <string>
#include <vector>
#include <stdexcept>
#include "../../stringhelper.h"
#include "../../tangible_filesystem.h"

//C# TO C++ CONVERTER NOTE: Forward class declarations:
namespace LibraryEditor { class WeMadeImage; }

namespace LibraryEditor
{
    class WeMadeLibrary
    {
    private:
        static const std::string WixExtention, WilExtention, WzlExtention, WzxExtention, MizExtention, MixExtention, LibExtention;

    public:
        std::vector<WeMadeImage*> Images;

    private:
        const std::string _fileName;

        std::vector<int> _palette;
        std::vector<int> _indexList;
        int _version = 0;

        BinaryReader *_bReader;
        FileStream *_fStream;
        std::string _MainExtention = WilExtention;
        std::string _IndexExtention = WixExtention;

        bool _initialized = false;

    public:
        unsigned char _nType = 0; //0 = .wil //1 = .wzl //2 = .wil new wemade design //3 = .wil mir3 //4 = .miz shanda mir3 // 5 = 32bit wil
    private:
        std::vector<unsigned char> ImageStructureSize = {8, 16, 16, 17, 16, 16}; //base size of an image structure

    public:
        virtual ~WeMadeLibrary()
        {
            delete _bReader;
            delete _fStream;
        }

        WeMadeLibrary(const std::string &name);

        void Initialize();

    private:
        void LoadImageInfo();

        void LoadIndexFile();

        void CheckImage(int index);

    public:
        void ToMLibrary();

    public:
        class WeMadeImage
        {
        public:
            const short Width, Height, X, Y, ShadowX, ShadowY;
            Rectangle *TrueSize;
            Bitmap *Image;
            long long CleanTime = 0;
            unsigned char nType = 0;
            bool bo16bit = false;
            int nSize = 0;
            bool boHasShadow = false;
            bool HasMask = false;
            Bitmap *MaskImage;

            virtual ~WeMadeImage()
            {
                delete TrueSize;
                delete Image;
                delete MaskImage;
            }

        private:
            int convert16bitTo32bit(int color);

            int WidthBytes(int nBit, int nWidth);

            std::vector<std::vector<unsigned char>> DecompressWemadeMir3(BinaryReader *BReader, short OutputWidth, short OutputHeight, int InputLength);

        public:
            WeMadeImage(BinaryReader *reader, unsigned char nType);

//C# TO C++ CONVERTER TODO TASK: C# 'unsafe' code is not converted by C# to C++ Converter:
//            public unsafe void CreateTexture(BinaryReader reader, int[] palette)
//            {
//                if (Width == 0 || Height == 0)
//                    return;
//                Image = new Bitmap(Width, Height);
//                MaskImage = new Bitmap(1, 1);
//
//                BitmapData data = Image.LockBits(new Rectangle(0, 0, Width, Height), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
//                byte[] bytes = new byte[0];
//                byte[] maskbytes = new byte[0];
//                MemoryStream output;
//                switch (nType)
//                {
//                    case 0: //wemade wil file uncompressed
//                        if (palette.Length > 256)
//                        {
//                            bo16bit = true;
//                            nSize = nSize * 2;
//                        }
//                        bytes = reader.ReadBytes(nSize);
//                        break;
//
//                    case 1: //shanda wzl file compressed
//                    case 4: //shanda miz file compressed
//                        output = new MemoryStream();
//                        Ionic.Zlib.ZlibStream deflateStream = new Ionic.Zlib.ZlibStream(output, Ionic.Zlib.CompressionMode.Decompress);
//                        deflateStream.Write(reader.ReadBytes(nSize), 0, nSize);
//                        bytes = output.ToArray();
//                        deflateStream.Close();
//                        output.Close();
//                        break;
//
//                    case 2:
//                    case 5:
//                        byte Compressed = reader.ReadByte();
//                        reader.ReadBytes(5);
//                        if (Compressed != 8)
//                        {
//                            bytes = reader.ReadBytes(nSize - 6);
//                            break;
//                        }
//                        MemoryStream input = new MemoryStream(reader.ReadBytes(nSize - 6));
//                        output = new MemoryStream();
//                        byte[] buffer = new byte[10];
//                        System.IO.Compression.DeflateStream decompress = new System.IO.Compression.DeflateStream(input, System.IO.Compression.CompressionMode.Decompress);
//                        int len;
//                        while ((len = decompress.Read(buffer, 0, buffer.Length)) > 0)
//                        {
//                            output.Write(buffer, 0, len);
//                        }
//                        bytes = output.ToArray();
//                        decompress.Close();
//                        output.Close();
//                        input.Close();
//                        break;
//
//                    case 3:
//                        MaskImage = new Bitmap(Width, Height);
//                        byte[][] DecodedPixels = DecompressWemadeMir3(reader, Width, Height, nSize);
//                        if (DecodedPixels != nullptr)
//                        {
//                            bytes = DecodedPixels[0];
//                            if (HasMask)
//                                maskbytes = DecodedPixels[1];
//                        }
//                        else
//                        {
//                            HasMask = false;
//                            bytes = new byte[Width * Height * 2];
//                        }
//                        break;
//                }
//                int index = 0;
//
//                if (bytes.Length <= 1)
//                {
//                    Image.UnlockBits(data);
//                    Image.Dispose();
//                    Image = nullptr;
//                    MaskImage.Dispose();
//                    return;
//                }
//
//                int * scan0 = (int * )data.Scan0;
//                {
//                    for (int y = Height - 1; y >= 0; y--)
//                    {
//                        for (int x = 0; x < Width; x++)
//                        {
//                            if (nType == 5)
//                            {
//                                scan0[y * Width + x] = BitConverter.ToInt32(bytes, index);
//                                index += 4;
//                                continue;
//                            }
//
//                            if (bo16bit)
//                                scan0[y * Width + x] = convert16bitTo32bit(bytes[index++] + (bytes[index++] << 8));
//                            else
//                                scan0[y * Width + x] = palette[bytes[index++]];
//                        }
//                        if (((nType == 1) || (nType == 4)) & (Width % 4 > 0))
//                            index += WidthBytes(bo16bit ? 16 : 8, Width) - (Width * (bo16bit ? 2 : 1));
//                    }
//                }
//                Image.UnlockBits(data);
//                index = 0;
//                if (HasMask)
//                {
//                    BitmapData Maskdata = MaskImage.LockBits(new Rectangle(0, 0, Width, Height), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
//                    int * maskscan0 = (int * )Maskdata.Scan0;
//                    {
//                        for (int y = Height - 1; y >= 0; y--)
//                        {
//                            for (int x = 0; x < Width; x++)
//                                maskscan0[y * Width + x] = convert16bitTo32bit(maskbytes[index++] + (maskbytes[index++] << 8));
//                        }
//                    }
//                    MaskImage.UnlockBits(Maskdata);
//                }
//            }
        };
    };
}
